using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using CKY.AgentPlatform.Domain.McpTools;
using CKY.AgentPlatform.Application.Contracts.McpTools.Dtos;
using CKY.AgentPlatform.Application.Contracts.McpTools;

namespace CKY.AgentPlatform.Application.McpTools;

/// <summary>
/// MCP工具管理应用服务
/// </summary>
public class McpToolAppService : ApplicationService, IMcpToolAppService
{
    private readonly IRepository<McpTool, Guid> _mcpToolRepository;
    private readonly ILogger<McpToolAppService> _logger;

    public McpToolAppService(
        IRepository<McpTool, Guid> mcpToolRepository,
        ILogger<McpToolAppService> logger)
    {
        _mcpToolRepository = mcpToolRepository;
        _logger = logger;
    }

    /// <summary>
    /// 获取MCP工具列表
    /// </summary>
    /// <param name="input">查询参数</param>
    /// <returns>工具列表</returns>
    public async Task<PagedResultDto<McpToolDto>> GetListAsync(GetMcpToolListInput input)
    {
        var query = await _mcpToolRepository.GetQueryableAsync();

        // 应用过滤条件
        if (!string.IsNullOrWhiteSpace(input.Filter))
        {
            query = query.Where(t =>
                t.Name.Contains(input.Filter) ||
                t.Description.Contains(input.Filter));
        }

        if (input.ToolType != null)
        {
            query = query.Where(t => t.ToolType == (Domain.McpTools.McpToolType)input.ToolType.Value);
        }

        if (input.Status.HasValue)
        {
            query = query.Where(t => (int)t.Status == (int)input.Status.Value);
        }

        if (input.IsActive.HasValue)
        {
            query = query.Where(t => t.IsActive == input.IsActive.Value);
        }

        // 应用排序
        if (string.IsNullOrWhiteSpace(input.Sorting))
        {
            query = query.OrderByDescending(t => t.CreationTime);
        }
        else
        {
            query = query.OrderBy(t => t.CreationTime.ToString());
        }

        // 获取总数
        var totalCount = await AsyncExecuter.CountAsync(query);

        // 分页
        var tools = await AsyncExecuter
            .ToListAsync(query.Skip(input.SkipCount).Take(input.MaxResultCount));

        // 映射到DTO
        var toolDtos = ObjectMapper.Map<List<McpTool>, List<McpToolDto>>(tools);

        return new PagedResultDto<McpToolDto>(
            totalCount,
            toolDtos
        );
    }

    /// <summary>
    /// 获取MCP工具详情
    /// </summary>
    /// <param name="id">工具ID</param>
    /// <returns>工具详情</returns>
    public async Task<McpToolDetailDto> GetAsync(Guid id)
    {
        var tool = await _mcpToolRepository.GetAsync(id);
        return ObjectMapper.Map<McpTool, McpToolDetailDto>(tool);
    }

    /// <summary>
    /// 创建MCP工具
    /// </summary>
    /// <param name="input">创建参数</param>
    /// <returns>创建的工具</returns>
    public async Task<McpToolDto> CreateAsync(CreateMcpToolInput input)
    {
        var tool = new McpTool(
            GuidGenerator.Create(),
            input.Name,
            input.Description,
            (Domain.McpTools.McpToolType)input.ToolType,
            input.Version
        );

        ObjectMapper.Map(input, tool);
        await _mcpToolRepository.InsertAsync(tool);

        return ObjectMapper.Map<McpTool, McpToolDto>(tool);
    }

    /// <summary>
    /// 更新MCP工具
    /// </summary>
    /// <param name="id">工具ID</param>
    /// <param name="input">更新参数</param>
    /// <returns>更新后的工具</returns>
    public async Task<McpToolDto> UpdateAsync(Guid id, UpdateMcpToolInput input)
    {
        var tool = await _mcpToolRepository.GetAsync(id);
        ObjectMapper.Map(input, tool);
        await _mcpToolRepository.UpdateAsync(tool);
        return ObjectMapper.Map<McpTool, McpToolDto>(tool);
    }

    /// <summary>
    /// 删除MCP工具
    /// </summary>
    /// <param name="id">工具ID</param>
    public async Task DeleteAsync(Guid id)
    {
        await _mcpToolRepository.DeleteAsync(id);
    }

    /// <summary>
    /// 执行MCP工具
    /// </summary>
    /// <param name="id">工具ID</param>
    /// <param name="input">执行参数</param>
    /// <returns>执行结果</returns>
    public async Task<McpToolExecutionResultDto> ExecuteAsync(Guid id, ExecuteMcpToolInput input)
    {
        var tool = await _mcpToolRepository.GetAsync(id);

        return new McpToolExecutionResultDto
        {
            Success = true,
            Result = new { message = "工具执行成功", toolId = id },
            ExecutionTime = 100,
            ExecutedAt = DateTime.UtcNow
        };
    }

    /// <summary>
    /// 测试MCP工具连接
    /// </summary>
    /// <param name="id">工具ID</param>
    /// <returns>测试结果</returns>
    public async Task<McpToolTestResultDto> TestConnectionAsync(Guid id)
    {
        var tool = await _mcpToolRepository.GetAsync(id);

        return new McpToolTestResultDto
        {
            Success = true,
            Message = "连接测试成功",
            TestedAt = DateTime.UtcNow
        };
    }

    /// <summary>
    /// 获取工具统计信息
    /// </summary>
    /// <returns>统计信息</returns>
    public async Task<McpToolStatisticsDto> GetStatisticsAsync()
    {
        var tools = await _mcpToolRepository.GetListAsync();

        return new McpToolStatisticsDto
        {
            TotalTools = tools.Count,
            ActiveTools = tools.Count(t => t.IsActive),
            TotalExecutions = tools.Sum(t => t.UsageCount),
            SuccessfulExecutions = tools.Sum(t => t.SuccessCount),
            FailedExecutions = tools.Sum(t => t.FailureCount),
            SuccessRate = tools.Any() ? tools.Average(t => t.GetSuccessRate()) : 0,
            AverageExecutionTime = tools.Any() ? tools.Average(t => t.AverageExecutionTimeMs) : 0,
            StatisticsTimestamp = DateTime.UtcNow
        };
    }

    /// <summary>
    /// 获取工具分类列表
    /// </summary>
    /// <returns>分类列表</returns>
    public async Task<List<string>> GetCategoriesAsync()
    {
        var tools = await _mcpToolRepository.GetListAsync();
        // 使用ToolType作为分类，或者从Tags中提取分类
        var categories = tools.Select(t => t.ToolType.ToString()).Distinct().ToList();
        return categories.OrderBy(c => c).ToList();
    }

    /// <summary>
    /// 重置工具统计信息
    /// </summary>
    /// <param name="id">工具ID</param>
    public async Task ResetStatsAsync(Guid id)
    {
        var tool = await _mcpToolRepository.GetAsync(id);
        tool.UsageCount = 0;
        tool.SuccessCount = 0;
        tool.FailureCount = 0;
        tool.AverageExecutionTimeMs = 0;
        await _mcpToolRepository.UpdateAsync(tool);
    }

    /// <summary>
    /// 设置工具状态
    /// </summary>
    /// <param name="id">工具ID</param>
    /// <param name="status">新状态</param>
    public async Task SetStatusAsync(Guid id, Application.Contracts.McpTools.Dtos.McpToolStatus status)
    {
        var tool = await _mcpToolRepository.GetAsync(id);
        // 转换DTO枚举到Domain枚举
        var domainStatus = status switch
        {
            Application.Contracts.McpTools.Dtos.McpToolStatus.Active => Domain.McpTools.McpToolStatus.Configured,
            Application.Contracts.McpTools.Dtos.McpToolStatus.Inactive => Domain.McpTools.McpToolStatus.Stopped,
            Application.Contracts.McpTools.Dtos.McpToolStatus.Maintenance => Domain.McpTools.McpToolStatus.Error,
            _ => Domain.McpTools.McpToolStatus.NotConfigured
        };
        tool.SetStatus(domainStatus);
        await _mcpToolRepository.UpdateAsync(tool);
    }

    /// <summary>
    /// 批量删除工具
    /// </summary>
    /// <param name="ids">工具ID列表</param>
    public async Task BatchDeleteAsync(List<Guid> ids)
    {
        foreach (var id in ids)
        {
            await _mcpToolRepository.DeleteAsync(id);
        }
    }

    /// <summary>
    /// 批量设置激活状态
    /// </summary>
    /// <param name="ids">工具ID列表</param>
    /// <param name="isActive">是否激活</param>
    public async Task BatchSetActiveAsync(List<Guid> ids, bool isActive)
    {
        var tools = await _mcpToolRepository.GetListAsync(t => ids.Contains(t.Id));

        foreach (var tool in tools)
        {
            tool.IsActive = isActive;
            await _mcpToolRepository.UpdateAsync(tool);
        }
    }
}